import { NMTopoBaseCommand } from '@app-cad/environments/nextmesh/types/command';
import { useEffect, useMemo, useState } from 'react';
import { ProjectType, TopoDialogProps } from '../type';

import { documentV2 } from '@app-cad/environments/nextmesh/domain';

import i18n from '@app-cad/common/utils/i18next';
import { UiSchema } from '@rjsf/utils';

import '../index.scss';
import { useCommand } from '@app-base/common/hooks/useCommand';
import { PickableCommandForm } from '@app-base/common/components/command-form/pickable';
import { PickInputRJSFFormat } from '@app-base/common/components/command-form/constants';
import { RadioButtonFields } from '../cmd-common/radioButtonFields';
import {pickedFaceData, pickedLineData, pickedVertexData } from '@amcax/base';

type FormDataType = {
  mode: string,
  target: pickedLineData[] | pickedFaceData[],
  isEmbeded: boolean,
  pointSource?: pickedVertexData[],
  lineSource?: pickedLineData[]
}
function PointsProjectDialog({ title, onClose }: TopoDialogProps) {
  const [formData, setFormData] = useState<FormDataType>({
    mode: ProjectType.PointProject,
    target: [],
    isEmbeded: true,
    pointSource: [],
    lineSource: []
  })
  useCommand('topo-pointProject', {
    onClose
  })
  useEffect(() => {
    setFormData({
      mode: formData.mode,
      target: [],
      isEmbeded: true,
      pointSource: [],
      lineSource: []
    })
  }, [formData.mode])
  const schema = useMemo(() => {
    const modeSchema = {
      mode: {
        type: 'string',
        enum: [ProjectType.PointProject, ProjectType.LineProject],
        default: ProjectType.PointProject
      },
    }
    const embed = {
      isEmbeded: {
        type: 'boolean',
        title: '是否嵌入目标对象',
        default: true
      }
    }
    if (formData.mode === ProjectType.PointProject) {
      return {
        properties: {
          mode: modeSchema,
          pointSource: {
            type: 'array',
            items: {
              type: 'string',
              enum: []
            },
            format: PickInputRJSFFormat.MultiPickVertex,
            uniqueItems: true,
          },
          target: {
            type: 'array',
            items: {
              type: 'string',
              enum: []
            },
            format: PickInputRJSFFormat.PickHigherDimensionOrVertex,
            uniqueItems: true,
          },
          ...embed,
        }
      }
    }
    if (formData.mode === ProjectType.LineProject) {
      return {
        properties: {
          mode: modeSchema,
          lineSource: {
            type: 'array',
            items: {
              type: 'string',
              enum: []
            },
            format: PickInputRJSFFormat.MultiPickCurve,
            uniqueItems: true,
          },
          target: {
            type: 'array',
            items: {
              type: 'string',
              enum: []
            },
            format: PickInputRJSFFormat.MultiPickFace,
            uniqueItems: true,
          },
          ...embed,
        }
      }
    }
    return schema
  }, [formData.mode])
  const uiSchema: UiSchema = {
    mode: {
      'ui:field': RadioButtonFields,
      'ui:options': {
        options: [
          {
            value: ProjectType.PointProject,
            label: '投影点'
          },
          {
            value: ProjectType.LineProject,
            label: '投影线'
          }
        ]
      }
    },
    pointSource: {
      'ui:placeholder': '请选择需要投影的点',
      'ui:autofocus': true
    },
    target: {
      'ui:placeholder': '请选择投影目标'
    },
    lineSource: {
      'ui:placeholder': '请选择需要投影的线',
      'ui:autofocus': true
    }
  }
  const isValid = () => {
    if (!formData) {
      return false
    }
    switch (formData.mode) {
      case ProjectType.PointProject:
        return formData.pointSource?.length > 0 && formData.target?.length > 0
      case ProjectType.LineProject:
        return formData.lineSource?.length > 0 && formData.target?.length > 0
      default:
        return false
    }
  }
  const handleSubmit = async () => {
    const { mode, target, isEmbeded, pointSource, lineSource } = formData
    if (!isValid()) {
      return
    }
    let sourceIds: string[] = []
    let targetIds: string[] = []
    if (mode === ProjectType.PointProject) {
      sourceIds = pointSource.map((v) => {
        return v.vertexId
      })
      targetIds = target.map((v) => {
        return v.meshId || v.edgeId
      })
    }
    if (mode === ProjectType.LineProject) {
      sourceIds = lineSource.map((v) => {
        return v.edgeId
      })
      targetIds = target.map((v) => {
        return v.meshId
      })
    }
    const params = {
      source: sourceIds,
      target: targetIds,
      isEmbeded
    }
    await documentV2.projectPoint(params, false)
    onClose()
  }
  return (
    <PickableCommandForm
      schema={schema}
      title={title}
      onClose={onClose}
      formData={formData}
      extraUiSchema={uiSchema}
      onSubmit={handleSubmit}
      isFormDataValid={isValid()}
      onChange={(data) => {
        setFormData(data)
      }}>
    </PickableCommandForm>
  )
}
export const cmdPointProject: NMTopoBaseCommand = {
  id: 'cmdPointLineProject',
  icon: 'commands/curved/point',
  label: 'command.topo.point-project',
  create: (label: string, onClose: () => void, props) => (
    <PointsProjectDialog
      title={i18n.t(label)}
      onClose={onClose}
      props={props}
      placement='topLeft'
    />
  ),
};
